package com.retail.lottery.colalottery.service.impl;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.retail.lottery.colalottery.constant.ColaHttpUrlConfig;
import com.retail.lottery.colalottery.constant.RedisConstant;
import com.retail.lottery.colalottery.enums.ErrorCodeEnum;
import com.retail.lottery.colalottery.exception.BusinessException;
import com.retail.lottery.colalottery.service.PlatformTenantClientService;
import com.retail.lottery.colalottery.utils.RedisUtils;
import com.retail.lottery.colalottery.vo.response.AccessTokenResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class PlatformTenantClientServiceImpl implements PlatformTenantClientService {

    @Value("${api-client-id}")
    private String lotteryClientId;
    @Value("${api-client-secret}")
    private String lotterySecret;
    @Value("${api-client-secret}")
    private String lotterySetupId;

    @Value("${api-bbq-client-id}")
    private String bbqClientId;
    @Value("${api-bbq-client-secret}")
    private String bbqSecret;
    @Value("${api-bbq-client-secret}")
    private String bbqSetupId;
    @Resource
    private ColaHttpUrlConfig colaHttpUrlConfig;

    @Override
    public String getAccessToken(String setupId) {
        String clientAccessTokenKey = null;
        String clientId,secret;
        if (lotterySetupId.equals(setupId)) {
            clientId = lotteryClientId;
            secret = lotterySecret;
            clientAccessTokenKey = String.format(RedisConstant.ACCESS_TOKEN, lotteryClientId, lotterySecret);
        } else {
            clientId = bbqClientId;
            secret = bbqSecret;
            clientAccessTokenKey = String.format(RedisConstant.ACCESS_TOKEN, bbqClientId, bbqSecret);
        }
        log.info("获取accessToken clientAccessTokenKey:{}", clientAccessTokenKey);
        String accessTokenCache = RedisUtils.getString(clientAccessTokenKey);
        Long expireIn = RedisUtils.getStringExpire(clientAccessTokenKey);
        log.info("accessToken cache info, get accessToken:{},expireIn:{}", accessTokenCache, expireIn);
        if (Objects.nonNull(accessTokenCache) && expireIn > 0) {
            return accessTokenCache;
        }
        String accessUrl = String.format(colaHttpUrlConfig.getAccessTokenUrl());
        log.info("获取accessToken结果,url:{}", accessUrl);
        AccessTokenResponse accessTokenResponse = null;
        Map<String, Object> formMap = new HashMap<>();
        formMap.put("clientId", clientId);
        formMap.put("secret", secret);
        HttpResponse response = HttpRequest.post(accessUrl)
                .form(formMap) // 添加Headers
                .execute();
        try {
            if (Objects.isNull(response) || response.getStatus() != HttpStatus.OK.value()) {
                throw new IOException("Unexpected code " + response);
            }
            log.info("获取accessToken结果,body:{}", JSONObject.toJSONString(response.body()));
            accessTokenResponse = JSONObject.parseObject(response.body(), AccessTokenResponse.class);
            if (Objects.isNull(accessTokenResponse) || StringUtils.isBlank(accessTokenResponse.getAccessToken())) {
                log.error("客户端登录获取accessToken失败,结果:{}", JSONObject.toJSONString(accessTokenResponse));
                throw new BusinessException(ErrorCodeEnum.GET_ACCESS_TOKEN_FAIL);
            }
            RedisUtils.saveString(clientAccessTokenKey, accessTokenResponse.getAccessToken(), accessTokenResponse.getExpiresIn(), TimeUnit.SECONDS);
            log.info("获取accessToken成功,结果:{}", JSONObject.toJSONString(accessTokenResponse));
            return accessTokenResponse.getAccessToken();
        } catch (IOException e) {
            log.error("客户端登录获取accessToken失败,发送异常", e);
            throw new BusinessException(ErrorCodeEnum.GET_ACCESS_TOKEN_FAIL);
        }
    }
}
